package com.copc.controller;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.copc.common.constants.CacheConstants;
import com.copc.common.constants.Constant;
import com.copc.common.service.RedisService;
import com.copc.common.util.CommonUtil;
import com.copc.copc.entity.MerchantConfig;
import com.copc.copc.entity.helper.MerchantStock;
import com.copc.copc.pojo.vo.order.*;
import com.copc.copc.service.IMerchantStockService;
import com.copc.mq.bean.SysConstant;
import com.copc.service.CopcService;
import com.copc.service.impl.MsgServiceImpl;
import io.swagger.annotations.Api;

import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import static java.lang.String.format;


/**
 * 1.预下单回调
 * 2.支付回调
 * 3.核销回调/反核销回调
 * 4.取消订单回调
 */
@Api("回调接口配置")
@RestController
@RequestMapping("/v2")
@Log4j2
public class CallbackContoller {

    @Resource
    private RedisService redisService;

    @Autowired
    private MsgServiceImpl msgService;

    @Autowired
    private CopcService copcService;

    @Autowired
    private IMerchantStockService merchantStockService;

    /**
     * 回调接口
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/result_callback")
    @ResponseBody
    public String createOrderCallback(@RequestBody String bodyJson, HttpServletRequest request) throws Exception {
        log.info("回调报文:" + bodyJson);
        // 返回消息
        ByteReturnVO byteReturnVO = new ByteReturnVO();
        Map<String,Object> requestMap = JSON.parseObject(bodyJson, Map.class);
        String msg = requestMap.get("msg").toString();
        String type = requestMap.get("type").toString();
        Map<String, Object> map = JSON.parseObject(msg, Map.class);
        String appId = map.get("app_id").toString();
        //验签校验消息是否有效
        if (!copcService.verify(bodyJson,request)) {
            log.error("验签校验");
//            return "error";
        }
        String orderNo = "";
        if(Constant.CREATE_ORDER.equals(type)){

            //预下单接口回调
            orderNo = map.get("order_id").toString();
            log.info("预下单接口回调："+orderNo);
            ByteMsgVO byteMsgVO = JSON.parseObject(msg, ByteMsgVO.class);
            String byteExtraStr = byteMsgVO.getCp_extra();
            ByteExtraVO byteExtraVO = JSON.parseObject(byteExtraStr, ByteExtraVO.class);
            String order_valid_time = byteExtraVO.getOrder_valid_time();
            redisService.setCacheObject(CacheConstants.COPC_ISV_ORDER_CACHE_KEY+orderNo,msg);
            String out_order_no =  getOrderNo();
            log.info("回调返回成功："+orderNo);
            byteReturnVO.setErr_no(0);
            byteReturnVO.setErr_tips("success");
            ByteReturnDataVO byteReturnDataVO = new ByteReturnDataVO();
            byteReturnDataVO.setOut_order_no(out_order_no);
            ByteReturnOrderEntrySchemaVO byteReturnOrderEntrySchemaVO = new ByteReturnOrderEntrySchemaVO();
            ByteParamsVO byteParamsVO = new ByteParamsVO();
            byteParamsVO.setOrder_id(orderNo);
            byteParamsVO.setAccount_id(byteExtraVO.getAccount_id());
            byteReturnOrderEntrySchemaVO.setParams(JSON.toJSONString(byteParamsVO));
            byteReturnDataVO.setOrder_entry_schema(byteReturnOrderEntrySchemaVO);
            List<ByteReturnOrderValidTimeVO> list = new ArrayList<>();
            if(CommonUtil.isNotEmpty(order_valid_time)){
                list = JSON.parseArray(order_valid_time,ByteReturnOrderValidTimeVO.class);
            }

            //商家库存操作
            byteReturnDataVO.setOrder_valid_time(list);
            byteReturnVO.setData(byteReturnDataVO);

            DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

            // 将字符串日期解析为 LocalDateTime 对象
            LocalDateTime dateTime = LocalDateTime.parse(byteExtraVO.getPickupTime(), inputFormatter);

            // 将 LocalDateTime 对象格式化为指定格式的字符串
            String formattedDateString = dateTime.format(outputFormatter);

            String redisKey = format("account::%s::order::%s::count", byteExtraVO.getAccount_id(), formattedDateString);

            Long currentDayStock = redisService.incrByCacheObject(redisKey);
            log.info("当日库存:{}",currentDayStock);

            QueryWrapper<MerchantStock> merchantStockWrapper = new QueryWrapper();
            merchantStockWrapper.eq("account_id",byteExtraVO.getAccount_id());//启用的商户配置
            merchantStockWrapper.eq("date",formattedDateString);
            MerchantStock merchantStock = merchantStockService.getOne(merchantStockWrapper);

            if(merchantStock != null) log.info("商家总库存:{}",merchantStock.getStock());

            //  库存不够
            if(merchantStock != null && currentDayStock > merchantStock.getStock()){

                byteReturnVO.setErr_no(1);
                byteReturnVO.setErr_tips("商家{"+formattedDateString+"}预约已满，请改约其他日期");

                log.info("回调返回失败 fail:{}",byteExtraVO.getAccount_id());

                //  库存减1
                redisService.decrByCacheObject(redisKey);
                return JSON.toJSONString(byteReturnVO);
            }

            log.info("回调返回成功 byteReturnVO："+JSON.toJSONString(byteReturnVO));

            //预下单回调，订单入库
            Map<String, Object> createMap = JSON.parseObject(msg, Map.class);
            createMap.put("out_order_no",out_order_no);
            copcService.saveOrder(JSON.toJSONString(createMap));

            return JSON.toJSONString(byteReturnVO);
        }else if(Constant.PAYMENT.equals(type)){
            //支付、取消订单接口回调
            orderNo = map.get("order_id").toString();
            log.info("支付、取消订单接口回调："+orderNo);
            String value = redisService.getCacheObject(CacheConstants.COPC_ISV_ORDER_CACHE_KEY+orderNo);
            if(CommonUtil.isNotEmpty(value)){
                log.info("orderinfo:"+value);
            }
            String status = map.get("status").toString();
            if("SUCCESS".equals(status)){//支付回调
                msgService.sendMsg(SysConstant.COPC_ISV_PAYED_QUEUE1,msg);
            }
            if("CANCEL".equals(status)){//取消回调
                msgService.sendMsg(SysConstant.COPC_ISV_CANCEL_QUEUE1,msg);
            }
        }else if(Constant.COUPON_VERIFY.equals(type)){

           String orderInfo = map.get("order_info").toString();
            Map<String, Object> orderInfoMap = JSON.parseObject(orderInfo, Map.class);
            if(CommonUtil.isNotEmpty(orderInfoMap)){
               orderNo = orderInfoMap.get("order_id").toString();
                //券核销接口回调
                log.info("券核销接口回调:"+orderNo);
               msgService.sendMsg(SysConstant.COPC_ISV_VOUCHER_QUEUE1,msg);
            }

        }else if(Constant.COUPON_VERIFY_CANCEL.equals(type)){
            //券撤销接口回调
            String orderInfo = map.get("order_info").toString();
            Map<String, Object> orderInfoMap = JSON.parseObject(orderInfo, Map.class);
            if(CommonUtil.isNotEmpty(orderInfoMap)){
                orderNo = orderInfoMap.get("order_id").toString();
                log.info("券撤销接口回调:"+orderNo);
            }
        }else{
            log.error("无效的回调type:"+type);
        }
        log.info("回调返回成功："+orderNo);
        byteReturnVO.setErr_no(0);
        byteReturnVO.setErr_tips("success");
        log.info("回调返回成功 byteReturnVO："+JSON.toJSONString(byteReturnVO));
        return JSON.toJSONString(byteReturnVO);
    }

    private Random random = new SecureRandom();

    private String getOrderNo() {
        int length = 6;
        String dateStr = CommonUtil.convertDateToStr(new Date(), "yyMMdd");
        String key = Constant.ORDERNO_SEQUENCE + dateStr;
        StringBuilder orderNo = new StringBuilder("");
        orderNo.append(dateStr);
        String random1 = RandomStringUtils.random(2, false, true);
        orderNo.append(random1);
        //两位随机码
        try {
            long sequence = redisService.incrByCacheObject(key);
            if (sequence == 1) {
                redisService.expire(key, 24 * 60 * 60);//过期时间设置为24小时
            }
            String seqStr = sequence + "";
            for (int i = 0; i < length - seqStr.length(); i++) {
                orderNo.append(0);
            }
            orderNo.append(seqStr);
        } catch (Exception e) {
            //logger.error("获取订单号失败", e);
            String random3 = RandomStringUtils.random(6, false, true);
            orderNo.append(random3);
        }
        String random2 = RandomStringUtils.random(4, false, true);
        orderNo.append(random2);
        return orderNo.toString();
    }

}
